FragmentTransaction 的 replace, add, hide, show 的使用和区别

引入

现在 APP 的主页面大多采用“单 Activity + 多 Fragment”的形式。多 Fragment 的使用需要解决两个问题:

  1. Fragment 怎么依附在 Activity 上
  2. Fragment 间的切换

对于第一个问题,可以利用 FrameLayout 来解决,FrameLayout 可以作为承载 Fragment 的容器,又可以成为 Activity 布局的一部分,这样就可以把 Fragment 和 Activity 连接起来。

重点是第二个问题,如果进行 Fragment 的切换。Fragment 的切换需要用到 FragmentTransaction。接下来就介绍一下 FragmentTransaction 的 创建以及它的 replace, add, hide, show 等方法,并学会如何使用这些方法完成 Fragment 的切换

FragmentTransaction 的创建和提交

首先是 FragmentTransaction 的创建:

1
2
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();

创建完后 FragmentTransaction 可以进行相应的操作(replace, add 等),具体操作之后再说。

最后记得进行提交:

1
ft.commit();

注意:

  1. 确保一次业务中,所有的事务通过同一个 FragmentTransaction 对象进行 commit。
  2. 如果一次业务中 commit 次数大于 1 次,那么就会报 java.lang.IllegalStateException: commit already called 异常,所以同一个 FragmentTransaction 对象只能 commit 一次

FragmentTransaction 进行事务处理

FragmentTransaction 在进行事务处理的时候,主要是调用这四个方法:replace, add, hide, show。它们的作用和区别如下:

方法表

操作 说明 备注
replace 先将之前存在于容器的 Fragment 全部移除(销毁),然后添加要显示的 Fragment(会重新执行一遍它的生命流程) 如果容器中已经存在和要添加的 Fragment 相同的实例(注意:相同是指同一个对象,同一个类但对象不同, 例如两次 new,则不算相同) 那么它只会将除此以外的其他 Fragment 清除,而不会再次添加相同的 Fragment 实例
add 不会将之前存在于容器的 Fragment 移除,而是继续往容器里添加 Fragment 1. 如果同一个对象多次添加会报错
2. 由于 add 操作不会将之前的 Fragment 删除,所以会造成多个 Fragment 重叠的现象,要解决这个问题可以使用 hide 隐藏之前的 Fragment
hide 隐藏容器中的 Fragment
show 将隐藏的 Fragment 显示出来 hide 和 show 是配对的,当要显示隐藏的 Fragment A 时,就 show(A);而对于其他 Fragment,则先 hide 起来,等之后要显示时再 show

实现切换 Fragment

通过上面介绍的几个方法可以实现 Fragment 的切换。有两种实现方式:

  1. 使用 replace
  2. add, hide, show 配合使用

第一种方式比较简单,想要显示哪个 Fragment 就 replace 它就行了。例如我要显示 FragmentA,那么我就这样写:

1
ft.replace(R.id.container, FragmentA);

其中 ft 是上面创建的 FragmentTransaction,R.id.container 是容器(FrameLayout) 的 id。

这种方式的优点是使用简单,但缺点是导致每次切换 Fragment 都会重新执行该 Fragment 的生命周期,影响性能。

由于会影响性能,所以不推荐第一种方式

重点看第二种方式,第二种方式需要 add, hide, show 配合使用,它的步骤如下:

  1. 如果要切换的 Fragment 还未创建,就先创建 Fragment 对象,并通过 add 方法添加到容器中
  2. 通过 hide 方法隐藏当前的 Fragment,然后通过 show 方法显示要切换的 Fragment

具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private void changeFragment(Fragment showFragment) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
if (showFragment == null) {
showFragment = new ShowFragment();
ft.add(R.id.container, showFragment);
}
// mCurrFragment 存储当前显示的 Fragment
if (mCurrFragment != null) {
ft.hide(mCurrFragment);
}
ft.show(showFragment);
mCurrFragment = showFragment;

ft.commit();
}

这种方式的优点当然是可以提高性能了,但是它也有缺点,就是可能会出现 Fragment 重叠的现象。例如你在切换了几次 Fragment 后,旋转屏幕,这时 Activity 发生重建,你会发现重建后的 Activity 上几个 Fragment 重叠在了一起(hide 失效了)。

解决方法的话,网上有很多这方面的文章,这里就不多说了。

参考

-------------    本文到此结束  感谢您的阅读    -------------
0%